#include "mydx10gameapp.h"
#include "util_sheetshader.h"
#include "CollisionDetection.h"



//-------------------GAME IMPLEMENTATION - METHOD OVERRIDES------------------------------------------------------

/******************************************
* Implementation of our Game's Windows
* Message Pump. All types are passed to 
* the Default Windows WndProc Handler.
******************************************/
LRESULT CALLBACK CMyDX10GameApp::customWndProc(HWND pwindowhandle, UINT pmessagetype, WPARAM pwparam, LPARAM plparam)
{
	return DefWindowProc(pwindowhandle,pmessagetype,pwparam,plparam);
}
	
/******************************************
* 
******************************************/
bool CMyDX10GameApp::customInit()
{
	//Build a Parameter List for OIS to get the ID of the Window we are controlling input for.
	ParamList			tpl;
	std::ostringstream	twndid;
	twndid << (size_t)this->_obj_wndapp->getWindowHandle();
	tpl.insert(std::make_pair( std::string("WINDOW"),twndid.str()));
	
	//Construct a new Input Manager from our Parameter List
	this->_obj_inputman = InputManager::createInputSystem(tpl);
	this->_obj_keyboard = (Keyboard*)this->_obj_inputman->createInputObject(OISKeyboard,false);
	this->_obj_mouse    = (Mouse*)this->_obj_inputman->createInputObject(OISMouse,false);

	//Set up Timer
	this->_obj_timer.resetTimer();
	this->_obj_timer.startTimer();

	//Load our Texture Shader
	std::wstring tshaderfile = this->getShaderDataDir().append(L"spritesheet.fx");
	LJMUUtilShaderTexSheet* ttexshader = new LJMUUtilShaderTexSheet();
	ttexshader->initialise(_obj_dxman->getDX10Device(),tshaderfile);

	//Load Our Sprite Char
	std::wstring tleveltexture = this->getImageDataDir().append(L"Level3.png");
	std::wstring tspritetexture = this->getSpriteDataDir().append(L"PlayerSpritesheet.png");
	std::wstring tseekertexture = this->getSpriteDataDir().append(L"Seeker.png");
	std::wstring tshapetexture = this->getSpriteDataDir().append(L"Shape.png");
	std::wstring ttilestexture = this->getImageDataDir().append(L"Tilemap3.png");

	//Setup Level Object
	this->_level = new CMyGameObject();
	this->_level->initialise(ttexshader,_obj_dxman->getDX10Device(),tleveltexture,1024,768,1);
	this->_level->setPosition(this->getScreenWidth()/2,this->getScreenHeight()/2);
	this->_level->update(1.0f);

	//Setup Tilemap Object
	this->_tiles = new CMyGameObject();
	this->_tiles->initialise(ttexshader,_obj_dxman->getDX10Device(),ttilestexture,1024,768,1);
	this->_tiles->setPosition(this->getScreenWidth()/2,this->getScreenHeight()/2);
	this->_tiles->update(1.0f);

	//Setup Hider Object
	this->_hider_object = new CMyShapeObject();
	this->_hider_object->initialise(ttexshader,_obj_dxman->getDX10Device(),tspritetexture,1500,75,20);
	this->_hider_object->setPosition(this->getScreenWidth()/2, this->getScreenHeight()/2);
	this->_hider_object->setActive(true);
	this->_hider_object->update(1.0f);
	
	//Setup Seeker Object
	this->_seeker_object = new CMyShapeObject();
	this->_seeker_object->initialise(ttexshader,_obj_dxman->getDX10Device(),tseekertexture,60,60,1);
	this->_seeker_object->setPosition(this->getScreenWidth()/2,this->getScreenHeight()/2);
	this->_seeker_object->update(1.0f);
	
	//Setup Game World Shapes
	this->_shape_object = new CMyShapeObject();
	this->_shape_object->initialise(ttexshader,_obj_dxman->getDX10Device(),tshapetexture,60,60,1);
	this->_shape_object->setPosition(300,300);
	this->_shape_object->setRect();
	
	/*for(int i=0; i < 100; i++)
	{
		CMyShapeObject* tobject = new CMyShapeObject();
		tobject->initialise(ttexshader,_obj_dxman->getDX10Device(),tshapetexture,60,60,1);
		tobject->setPosition(500,500);
		this->_objectlist.push_back(tobject);

	}*/

	//Binding each quarter of the gameworld to a RECT
	RECT rctRed;
	rctRed.left = this->getScreenWidth() - this->getScreenWidth();  
	rctRed.top = this->getScreenHeight() / 2;  
	rctRed.right  = this->getScreenWidth() / 2;  
	rctRed.bottom = this->getScreenHeight();

	RECT rctBlue;
	rctBlue.left = this->getScreenWidth() / 2;
	rctBlue.top = this->getScreenHeight() / 2;
	rctBlue.right = this->getScreenWidth();
	rctBlue.bottom = this->getScreenHeight();

	RECT rctGreen;
	rctGreen.left = this->getScreenWidth() - this->getScreenWidth();
	rctGreen.top = this->getScreenHeight() - this->getScreenHeight();
	rctGreen.right = this->getScreenWidth() / 2;
	rctGreen.bottom = this->getScreenHeight() / 2;

	RECT rctYellow;
	rctYellow.left = this->getScreenWidth() / 2;
	rctYellow.top = this->getScreenHeight() - this->getScreenHeight();
	rctYellow.right = this->getScreenWidth();
	rctYellow.bottom = this->getScreenHeight() / 2;


	return true;
}





/******************************************
* 
******************************************/
bool CMyDX10GameApp::customUpdate()	
{
	_obj_keyboard->capture();

	static float lastupdate = 0;

	this->_obj_timer.updateTimer();
	float ttpf = this->_obj_timer.getTimePerFrame();

	//Determines which player it is to go
	if(_obj_keyboard->isKeyDown(KeyCode::KC_SPACE))
	{
		if(this->_hider_object->isActive() == true)
		{
			this->_hider_object->setActive(false);
			MessageBox(NULL, L"Seeker's Turn to Seek!", L"Player 2", NULL);
			//this->g_audioState.pSoundBank->Play(g_audioState.iZap, 0, 0, NULL);
		}
		else
		{
			this->_hider_object->setActive(true);
			MessageBox(NULL, L"Hider's Turn to Hide!", L"Player 1", NULL);
		}
	}

	//----------HIDING PLAYER CONTROLS------------------------------------------------
	//Controls WASD
	if(_obj_keyboard->isKeyDown(KeyCode::KC_A) && this->_hider_object->isActive() == true)
		this->_hider_object->addPosition(-200.0f * ttpf,0.0f);
	else if(_obj_keyboard->isKeyDown(KeyCode::KC_D) && this->_hider_object->isActive() == true)
		this->_hider_object->addPosition(200.0f * ttpf,0.0f);

	//If the xposition of the hider object goes beyond the length of the window, 
	//it makes the object appear at the other side of the window
	if(this->_hider_object->getXPos() <0)
		this->_hider_object->setXPos(1024);
	else if(this->_hider_object->getXPos() >1024)
		this->_hider_object->setXPos(0);

	if(_obj_keyboard->isKeyDown(KeyCode::KC_W) && this->_hider_object->isActive() == true)
		this->_hider_object->addPosition(0.0f,200.0f * ttpf);
	else if(_obj_keyboard->isKeyDown(KeyCode::KC_S) && this->_hider_object->isActive() == true)
		this->_hider_object->addPosition(0.0f,-200.0f * ttpf);

	//If the yposition of the hider object goes beyond the length of the window, 
	//it makes the object appear at the other side of the window
	if(this->_hider_object->getYPos() <0)
		this->_hider_object->setYPos(768);
	else if(this->_hider_object->getYPos() >768)
		this->_hider_object->setYPos(0);


	//Rotate the hiders object
	lastupdate += ttpf;
	
	if(lastupdate > 0.05)
	{
		if(this->_obj_keyboard->isKeyDown(KeyCode::KC_Q))
		{
			this->_hider_object->addRotation(-5.0f);
			lastupdate = 0;
		}
		else if(this->_obj_keyboard->isKeyDown(KeyCode::KC_E))
		{
			this->_hider_object->addRotation(5.0f);
			lastupdate = 0;
		}
	}



	lastupdate += ttpf;

	//Only allow a key press every 0.2 of a second
	//Moves on to the next shape in the sprtesheet
	if(lastupdate > 0.3)
	{
		if(_obj_keyboard->isKeyDown(KeyCode::KC_F))
		{
			this->_hider_object->setCurrentFrame(this->_hider_object->getCurrentFrame() + 1);
			lastupdate = 0;
		}
		else if(_obj_keyboard->isKeyDown(KeyCode::KC_G))
		{
			this->_hider_object->setCurrentFrame(this->_hider_object->getCurrentFrame() - 1);
			lastupdate = 0;
		}
	}

	//When switching through shapes, always keeps the same colour
	if(this->_hider_object->getCurrentFrame() == 4)
	{
		this->_hider_object->setCurrentFrame(0);
	}
	else if(this->_hider_object->getCurrentFrame() == 9)
	{
		this->_hider_object->setCurrentFrame(5);
	}
	else if(this->_hider_object->getCurrentFrame() == 14)
	{
		this->_hider_object->setCurrentFrame(10);
	}
	else if(this->_hider_object->getCurrentFrame() == 19)
	{
		this->_hider_object->setCurrentFrame(15);
	}

	//Changes the colour of the selected shape
	if(lastupdate > 0.3)
	{
		if(_obj_keyboard->isKeyDown(KeyCode::KC_C))
		{
			if(this->_hider_object->getCurrentFrame() < 14)
			{
				this->_hider_object->setCurrentFrame(this->_hider_object->getCurrentFrame() + 5);
				lastupdate = 0;
			}
			else if(this->_hider_object->getCurrentFrame() >= 14)
			{
				this->_hider_object->setCurrentFrame(this->_hider_object->getCurrentFrame() - 15);
				lastupdate = 0;
			}
		
		}
	}
	//--------------------------------------------------------------------------------------------

	//------------SEEKER PLAYER CONTROLS----------------------------------------------------
	//Seeker controls UP, DOWN, LEFT, RIGHT
	if(_obj_keyboard->isKeyDown(KeyCode::KC_LEFT) && this->_hider_object->isActive() == false)
		this->_seeker_object->addPosition(-200.0f * ttpf,0.0f);
	else if(_obj_keyboard->isKeyDown(KeyCode::KC_RIGHT) && this->_hider_object->isActive() == false)
		this->_seeker_object->addPosition(200.0f * ttpf,0.0f);

	//If the xposition of the seeker object goes beyond the length of the window, 
	//it makes the object appear at the other side of the window
	if(this->_seeker_object->getXPos() <0)
		this->_seeker_object->setXPos(1024);
	else if(this->_seeker_object->getXPos() >1024)
		this->_seeker_object->setXPos(0);

	if(_obj_keyboard->isKeyDown(KeyCode::KC_UP) && this->_hider_object->isActive() == false)
		this->_seeker_object->addPosition(0.0f,200.0f * ttpf);
	else if(_obj_keyboard->isKeyDown(KeyCode::KC_DOWN) && this->_hider_object->isActive() == false)
		this->_seeker_object->addPosition(0.0f,-200.0f * ttpf);

	//If the yposition of the seeker object goes beyond the length of the window, 
	//it makes the object appear at the other side of the window
	if(this->_seeker_object->getYPos() <0)
		this->_seeker_object->setYPos(768);
	else if(this->_seeker_object->getYPos() >768)
		this->_seeker_object->setYPos(0);
	//-----------------------------------------------------------------------------------

	/*****std::vector<CMyShapeObject*>::iterator iter;

	for(iter = this->_objectlist.begin(); iter != this->_objectlist.end(); iter++)
	{
		CMyShapeObject* tobject = (*iter);
		tobject->update(ttpf);
	}****/
	
	//--------------------------------------------------------------------------------------------

	//------------COLLISION DETECTION----------------------------------------------------


	//Temporary variable to pass in the collisiond etection function
	RECT temprect = {0,0,0,0};
	
	// Call isColiding Method here and doing the collision detection
	if(_obj_keyboard->isKeyDown(KeyCode::KC_RETURN))
	{
		if(CCollisionDetection::isColliding(_hider_object, _seeker_object, &temprect))
		{
			//Msgbox(NULL, contents of messagebox, title of messagebox, NULL)
			MessageBox(NULL, L"Well Done, You Have Found the Hider", L"YAY", NULL);
			this->_hider_object->setPosition(this->getScreenWidth()/2, this->getScreenHeight()/2);
			this->_seeker_object->setPosition(this->getScreenWidth()/2, this->getScreenHeight()/2);
		}
		else 
		{
			MessageBox(NULL, L"Sorry, Try Again", L"Sorry", NULL);
		}
		
		
	}



	this->_shape_object->update(ttpf);
	this->_hider_object->update(ttpf);
	this->_seeker_object->update(ttpf);
	
	return true;
}


/******************************************
* 
******************************************/
bool CMyDX10GameApp::customRender()
{
	this->_level->render(1.0f,this->_dx_mat_view,this->_dx_mat_ortho);
	this->_tiles->render(1.0f,this->_dx_mat_view,this->_dx_mat_ortho);
	this->_hider_object->render(1.0f,this->_dx_mat_view,this->_dx_mat_ortho);
	this->_seeker_object->render(1.0f,this->_dx_mat_view,this->_dx_mat_ortho);

	//this->_shape_object->render(1.0f,this->_dx_mat_view,this->_dx_mat_ortho);

	//std::vector<CMyShapeObject*>::iterator iter;

	//for(iter = this->_objectlist.begin(); iter != this->_objectlist.end(); iter++)
	//{
	//	CMyShapeObject* tobject = (*iter);
	//	tobject->render(1.0f,this->_dx_mat_view,this->_dx_mat_ortho);
	//}
	
	return true;
}

/******************************************
* 
******************************************/
bool CMyDX10GameApp::customCleanup()
{
	this->_hider_object->cleanup();
	this->_seeker_object->cleanup();
	this->_shape_object->cleanup();
	return true;
}